/**
 * 该文件创建后端服务，使用 ws 模块来创建 socket 服务
 */

// 引入 ws 模块
const WebSocket = require("ws");
const querystring = require("querystring");

// 创建 WebSocket 服务
const wss = new WebSocket.Server({
  port: 3000, // 设置服务监听的端口号
});

// 用于收集当前的客户端 socket 实例
let clients = [];

/**
 * 广播
 * @param {*} msg 消息
 */
function broadcast(msg) {
  clients.forEach((ws) => {
    ws.send(msg);
  });
}

// 监听连接建立
//    socket 连接实例
//    request 请求对象
wss.on("connection", (socket, request) => {
  // 1. 获取 url 地址上传递过来的 nickName
  //    '/?nickName=%E5%BC%A0%E4%B8%89'
  const url = request.url;
  //    'nickName=%E5%BC%A0%E4%B8%89'
  const search = url.split("?")[1];
  const query = querystring.parse(search);
  const nickName = query.nickName;

  // 2. 将 nickName 与当前的 scoket 给关联起来
  socket.nickName = nickName;

  // 3. 将 当前 socket 追加到 clients
  clients.push(socket);

  // 4. 给聊天室中的成员发送一个消息
  // socket.send(`nickName=管理员&msg=欢迎${nickName}加入聊天室`);
  // clients.forEach((ws) => {
  //   ws.send(`nickName=管理员&msg=欢迎${nickName}加入聊天室`);
  // });
  broadcast(`nickName=管理员&msg=欢迎${nickName}加入聊天室`);

  // 5. 监听客户端发来的消息
  socket.onmessage = function (event) {
    // 消息内容
    const str = event.data;

    // 广播
    broadcast(`nickName=${socket.nickName}&msg=${str}`);
    // clients.forEach((ws) => {
    //   ws.send(`nickName=${socket.nickName}&msg=${str}`);
    // });
  };

  // 6. 监听客户端断开链接
  socket.onclose = function (event) {
    // 1. 将 当前 socket 从 clients 移除
    clients = clients.filter((ws) => ws !== socket);

    // 广播
    broadcast(`nickName=管理员&msg=${socket.nickName}离开聊天室`);
  };
});
